/*
 *  Cell.cpp
 *  
 *
 *  Created by Daniel Condon on 25/07/12.
 *  Copyright 2012 __MyCompanyName__. All rights reserved.
 *
 */
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include "Cell.h"

using namespace std;

//--Default constructor
//--will pass zeros to secondary constructor
Cell::Cell(){
	Cell(0, 0);
}

/*--Secondary Constructor
 will pass x and y values to final constructor and zeros as the popluation
 Params:
 Parameter(0) : x coordinate of the cell
 Parameter(1) : y coordinate of the cell
 Pre: Parameter(0&1) not outside the limits of the matrix	 
 */
Cell::Cell(int setX, int setY){
	Cell(setX, setY, 0);
}

/*--Terciary Constructor
 Params:
 Parameter(0) : x coordinate of the cell
 Parameter(1) : y coordinate of the cell
 Parameter(2) : maximum population of the cell
 Pre: Parameter(0&1) not outside the limits of the matrix	
 */
Cell::Cell(int setX, int setY, int setMax){
	px = setX;
	py = setY;
	
	maxCreatures = setMax;
	migrants = 0;
	currentCreatures = 0;
	Spreadable = true;
}

/*--Final Constructor
 Params:
 Parameter(0) : x coordinate of the cell
 Parameter(1) : y coordinate of the cell
 Parameter(2) : maximum population of the cell
 Parameter(3) : terrain type of the cell
 Pre: Parameter(0&1) not outside the limits of the matrix
 Parameter(3) is a valid terrain type
 */
/*Cell::Cell(int setX, int setY, int setMax, string cellTerrain){
	px = setX;
	py = setY;
	
	maxCreatures = setMax;
	migrants = 0;
	currentCreatures = 0;
	cout << px << ":" << py << endl;
	PrintCellPos();
}*/

void Cell::setCellPos(int a, int b){
	px = a;
	py = b;
}

/*--will set  parameter 0 & 1 to the grid coordinates x & y respectively
 Params:
 Parameter(0) : int pointer, will be set to the cells X coordinate
 Parameter(1) : int pointer, will be set to the cells Y coordinate
 */
void Cell::getCellPos(int* xID, int* yID){
	*xID = px;
	*yID = py;
}

/*--will return the cells current population
 Return : Cells current population
 */
double Cell::getCellCurrent(){
	return currentCreatures;
}

/*--will return the cells maximum population
 Return : cells maximum population
 */
double Cell::getCellMax(){
	return maxCreatures;
}

/*--This function will return current percentage of maximum load
 Pre : cell population and maximum both not NULL
 Returns : % of cell max population
 */
double Cell::getCellPercent(){
	return (double)currentCreatures/(double)maxCreatures;
}

/*--This function will return the number of migrants sent
 Pre : number of migrants is not NULL or negative
 Return : return number of migrants received during current tick
 */
int Cell::getMigrantNum(){
	return migrants;
}

/*--This function will remove the migrants from this cell 
 in preperation for their move
 Params:
 Parameter(0) : number of migrants moving
 Pre : number of migrants is not NULL or negative
 */
void Cell::sendMigrants(int numMigrants){
	currentCreatures -= numMigrants;
}

/*--This function will receive the migrants without adding them 
 to the total population
 Params:
 Parameter(0) : number of incoming migrants
 Pre : number of migrants is not NULL or negative
 */
void Cell::receiveMigrants(int numMigrants){
	if (numMigrants > 0) {
		recieved = true;
		migrants += numMigrants;
	}
}

/*--This function will add the migrants to the population
 */
void Cell::incorporateMigrants(){
	if (recieved) {
		currentCreatures += migrants;
		if (currentCreatures > maxCreatures) {
			currentCreatures = maxCreatures;
		}
		recieved = false;
	}
	migrants = 0;
}


/*--This function will receive the amount of growth made during current tick
 */
void Cell::applyGrowth(int growth){
	currentCreatures += growth;
	if (currentCreatures > maxCreatures) {
		currentCreatures = maxCreatures;
	}
}

/*--This function will place a barrier at one of the sides
 (East, North, West, South) 
 Params:
 Parameter(0) : Side to place the barrier
 Pre : side input between 1 and 4 inclusive
 */
void Cell::PlaceBarrier(int side){
	//0 - E 
	//1 - N
	//2 - W
	//3 - S
	switch (side) {
		case 0:
			barriers[0] = true;
			break;
		case 1:
			barriers[1] = true;
			break;
		case 2:
			barriers[2] = true;
			break;
		case 3:
			barriers[3] = true;
			break;
		default:
			break;
	}
	if ((barriers[0]) && (barriers[1]) && (barriers[2]) && (barriers[3])) {
		Spreadable = false;
	}
}

/*--This function will remove a barrier at one of the sides
 (East, North, West, South) 
 Params:
 Parameter(0) : Side to remove the barrier
 Pre : side input between 1 and 4 inclusive
 */
void Cell::RemoveBarrier(int side){
	switch (side) {
		case 0:
			barriers[0] = false;
			break;
		case 1:
			barriers[1] = false;
			break;
		case 2:
			barriers[2] = false;
			break;
		case 3:
			barriers[3] = false;
			break;
		default:
			break;
	}
	Spreadable = true;
}

/*--This function will check if a barrier is on the given side
 (East, North, West, South)
 Params:
 Parameter(0) : Side to check the barrier
 Pre : side input between 1 and 4 inclusive
 Return : wether the side has a barrier
 */
bool Cell::hasBarrier(int side){
	return barriers[side];
}

/*--This function will check if the cell can spread
 Return : if cell has 4 barriers,  will return false
 */
bool Cell::canSpread(){
	return Spreadable;
}